<?php

namespace App\Service\OpenShop\Wap;

use App\Console\Commands\Fee\InitFeeDate;
use App\Enums\BaseErrorCode;
use App\Enums\Check\CheckEnum;
use App\Enums\Fee\FeeEnum;
use App\Enums\OpenShop\InvestmentPromotion\ErrCode;
use App\Enums\OpenShop\InvestmentPromotion\MainProcessEnum;
use App\Enums\OpenShop\InvestmentPromotion\OpenShopCacheEnum;
use App\Enums\OpenShop\InvestmentPromotion\SignOrderEnum;
use App\Enums\OpenShop\InvestmentPromotion\UploadFileResourceEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Enums\Pay\RmsPayEnum;
use App\Events\OpenShop\OpenShopProcessEvent;
use App\Events\OpenShop\OrderPaymentSucceededEvent;
use App\Events\OpenShop\SignSiteMissionEvent;
use App\Exceptions\Custom\CustomHttpResponseException;
use App\Exceptions\Custom\ResponseHttpException;
use App\Kuafu\Shop\Enum\ShopCodeEnum;
use App\Library\FeiShu\SendFs;
use App\Library\Rms\RmsPayApi;
use App\Library\Rms\RmsShopApi;
use App\Library\Rms\RmsUserApi;
use App\Models\Appraise\AppraiseModel;
use App\Models\Cruise\CruiseCheckAgainstModel;
use App\Models\Fee\FeeAnnualOrderModel;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopAddressModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopContractTemplateModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderLogModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderPayHistoryModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSiteMissionModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignCostMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignSoftOutfitMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUploadFileResourceModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserContractModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Models\System\SystemNotifyCenterModel;
use App\Remote\Orm\OrmNewOrderRemote;
use App\Remote\Rms\RmsUserRemote;
use App\Service\Common\SmsService;
use App\Service\Cruise\Check\CruiseCheckAgainstShopMappingsService;
use App\Service\Cruise\Shop\CruiseShopLicenseRecordsService;
use App\Service\OpenShop\Feishu\BaseService;
use App\Service\OpenShop\Feishu\KfosService;
use App\Service\OpenShop\Feishu\MainProcessService;
use App\Service\OpenShop\Feishu\ShopTagsService;
use App\Service\OpenShop\Feishu\SiteMissionService;
use App\Service\OpenShop\Feishu\UploadFileResourceService;
use App\Service\OpenShop\Import\HistoryOrder\HistoryOrderExecute;
use App\Service\OpenShop\Import\HistoryOrder\HistoryOrderParam;
use App\Service\OpenShop\Message\SendFsService;
use App\Service\OpenShop\User\RmsUserService;
use App\Service\OpenShop\UserContractService;
use App\Service\Pay\PayParamService;
use App\Service\Pay\SysType\BasePaySysTypeService;
use App\Service\Schedule\ScheduleService;
use App\Service\System\SystemNotifyService;
use App\Service\WorkOrder\Appraise\NotifyService;
use App\Service\WorkOrder\ProblemFeedbackService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Kuafu\GeneralFs\BuildFs;
use Kuafu\GeneralFs\CardStyle\FsCardGrid;
use Kuafu\GeneralFs\FsCardEstablish;

class SignOrderService extends BaseService
{
    private string $orderNo = '';

    private ?OpenShopSignOrderModel $signOrder = null;
    private PayParamService         $payParam;

    private BasePaySysTypeService $paySysTypeService;

    const SIGN_STEP_PAY      = 1; // 支付阶段
    const SIGN_STEP_CONTRACT = 2; // 签约阶段
    const SIGN_STEP_FINISH   = 3; // 完成

    /**
     * @param string $orderNo 自动生成signOrder对象
     * @param OpenShopSignOrderModel|null $signOrder 依赖注入signOrder对象
     * @param bool $autoRelationShip 是否自动关联相关RelationShip
     */
    public function __construct(
        string $orderNo = '',
        ?OpenShopSignOrderModel $signOrder = null,
        bool $autoRelationShip = true,
        bool $withoutDel = false
    ) {
        if ($signOrder instanceof OpenShopSignOrderModel) {
            $this->signOrder = $signOrder;
            $this->orderNo   = $this->signOrder->orderNo;
        } elseif ($orderNo) {
            $this->orderNo   = $orderNo;
            $this->signOrder = OpenShopSignOrderModel::query()
                                                     ->where('orderNo', $this->orderNo)
                                                     ->first();
        }

        if (!$this->signOrder) {
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_NO_NULL));
        }

        if (!$withoutDel && $this->signOrder->status == SignOrderEnum::ORDER_STATUS_NO) {
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_STATUS_DEL));
        }

        // 自动带上需要的RelationShip
        if ($autoRelationShip) {
            $_ = $this->signOrder->contractRel;
        }
    }

    /**
     * 获取当前signOrder对象
     * @return OpenShopSignOrderModel|null
     */
    public function getSignOrder(): ?OpenShopSignOrderModel
    {
        return $this->signOrder;
    }

    /**
     * 获取商家app中的签约订单
     * @param bool $throwException
     * @return OpenShopSignOrderModel|null
     */
    public function getSignOrderInMerchant(bool $throwException = true): ?OpenShopSignOrderModel
    {
        // 在商家APP无需展示的阶段
        if ($this->signOrder->step < SignOrderEnum::STEP_1) {

            if ($throwException) {
                throw new CustomHttpResponseException(
                    ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_NULL_IN_MERCHANT)
                );
            } else {
                return null;
            }
        }

        return $this->signOrder;
    }

    /**
     * 获取支付、合同签署详情
     * @return array
     */
    public function getPayContractDetailByStep(): array
    {
        // 订单已作废
        if ($this->signOrder->status == SignOrderEnum::ORDER_STATUS_NO) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_STATUS_DEL)
            );
        }

        // 未到支付阶段
        if ($this->signOrder->step == SignOrderEnum::STEP_1) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_BEFORE_PAY)
            );
        }

        // 支付
        if ($this->signOrder->step == SignOrderEnum::STEP_2 || $this->signOrder->step == SignOrderEnum::STEP_3) {
            return $this->payDetail();
        }

        // 签合同
        if ($this->signOrder->step == SignOrderEnum::STEP_4) {
            return ['step' => self::SIGN_STEP_CONTRACT];
        }

        // 支付定金尾款
        $nowStepStatus = OpenShopMainProcessModel::query()
                                                 ->where('id', $this->signOrder->mainProcessId)
                                                 ->value('nowStepStatus');

        if ($nowStepStatus >= MissionTemplateEnum::STEP_STATUS_5) {

            list($isFinalPay, $lastPrice, $depositAmount) = UserContractService::getLastPrice($this->signOrder);
            if ($isFinalPay && $lastPrice > 0) {
                return $this->payDetail();
            }
        }

        // 完成
        return ['step' => self::SIGN_STEP_FINISH];
    }

    /**
     * 在线签约-支付详情
     * @param string $orderNo
     * @return array
     */
    private function payDetail(): array
    {
        // 招商经理详情
        $managerId = (string)$this->signOrder->investmentManagerId;
        if ($managerId) {
            $user   = RmsUserService::getRmsUserInfoByUserIds($managerId, [], true);
            $mobile = $user['data'][0]['mobile'] ?? '';
        } else {
            $mobile = '';
        }

        return [
            'step'  => self::SIGN_STEP_PAY, // 1支付 2签约
            'pay'   => array_merge([

                // 0待支付 1部分 1ok
                'payStatus'       => $this->signOrder->payStatus,

                // 签约倒计时
                'deadLineSeconds' => $this->signOrder->contractRel->createdAt->timestamp + SignOrderEnum::SIGN_DEADLINE_SECONDS - time(),
            ], $this->orderPayValidConfig(CheckEnum::SYS_TYPE_OPEN_SHOP_LEAGUE, $this->signOrder)),
            'order' => [
                'orderNo' => $this->orderNo,
                'manager' => $this->signOrder->investmentManagerName,
                'phone'   => $mobile, // 手机号用实时的
            ],
        ];
    }

    // 订单的支付相关信息
    private function orderPayValidConfig(int $sysType, Model $orderModel): array
    {
        switch ($sysType) {
            case CheckEnum::SYS_TYPE_OPEN_SHOP_DESIGN:
            case CheckEnum::SYS_TYPE_OPEN_SHOP_DECORATE:
                $bizId = $orderModel->preparationNo;
                break;
            case CheckEnum::SYS_TYPE_ANNUAL_FEE:
                $bizId = $orderModel->feeOrderNo;
                break;
            case CheckEnum::SYS_TYPE_AGAINST:
                $bizId = $orderModel->serialNum;
                break;
            default:
                $bizId = $orderModel->orderNo;
                break;
        }

        if ($sysType == CheckEnum::SYS_TYPE_ANNUAL_FEE) {
            $paidPrice = (int)optional($orderModel)->payPrice;
        } else {
            // 已支付的总金额
            $paidPrice = (int)$this->signOrder
                ->payHistoryRel
                ->where('sysType', $sysType)
                ->where('payStatus', OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK)
                ->where('bizId', $bizId)
                ->sum('payPrice');
        }

        // 通用的自定义的最低、最高金额
        list($commonPayMin, $commonPayMax) = SignOrderEnum::getCommonPartPayRange();

        $arr = [
            // 金额明细
            'lists'      => $lists = BasePaySysTypeService::getIns($sysType, $this->signOrder, $orderModel)
                                                          ->priceLists(),

            // 合同金额合计
            'total'      => $total = (int)collect($lists)->sum('price'),

            // 待支付总金额
            'waitPaySum' => $waitPaySum = $total - $paidPrice,

            // 最低支付金额 - 下面重写
            'waitPayMin' => 0,

            // 单笔最高支付金额 - 下面重写
            'waitPayMax' => 0,
        ];

        // 普通订单=定金
        $arr['isFinalPay'] = false;

        // 加盟费
        if ($sysType == CheckEnum::SYS_TYPE_OPEN_SHOP_LEAGUE) {

            // 判断是定金还是尾款
            list($isFinalPay, $lastPrice, $depositAmount) = UserContractService::getLastPrice($this->signOrder);

            // 有定金的情况
            if ($depositAmount) {

                // 尾款
                if ($isFinalPay) {

                    $shopCount = $this->signOrder->contractRel->shopCount;
                    $depositOne = $depositAmount / $shopCount;

                    // 主单尾款的已支付金额，要-子单的定金
                    if ($this->signOrder->mainProcessRel->childOrder == MainProcessEnum::CHILD_ORDER_0) {

                        $deposit   = $depositOne * ($shopCount - 1);
                        $paidPrice -= $deposit;
                    } else {
                        // 子单尾款的已支付金额，要+子单的定金
                        $paidPrice += $depositOne;
                    }

                    $arr['listsFoot'] = [
                        [
                            'name'  => '支付总计',
                            'price' => $total,
                        ],
                        [
                            'name'  => '已支付',
                            'price' => $paidPrice,
                        ],
                        [
                            'name'  => '还需支付',
                            'price' => $lastPrice,
                        ]
                    ];

                    $arr['isFinalPay'] = true;

                } else {

                    // 定金
                    $arr['listsFoot'] = [
                        [
                            'name'  => '支付总计',
                            'price' => $total,
                        ],
                        [
                            'name'  => '定金金额',
                            'price' => $depositAmount,
                        ],
                        [
                            'name'  => '还需支付',
                            'price' => $lastPrice,
                        ]
                    ];
                }

                // 待支付总金额
                $arr['waitPaySum'] = $waitPaySum = $lastPrice;
            }
        }

        // 最低支付金额
        $arr['waitPayMin'] = ($commonPayMin < $waitPaySum) ? $commonPayMin : $waitPaySum;

        // 单笔最高支付金额
        $arr['waitPayMax'] = ($commonPayMax < $waitPaySum) ? $commonPayMax : $waitPaySum;

        return $arr;
    }

    /**
     * 订单支付金额校验
     * @param int $amount
     * @return bool
     */
    private function orderPayValid(int $sysType, int $amount, Model $orderModel): bool
    {
        $validConfig = $this->orderPayValidConfig($sysType, $orderModel);

        // 能支付 - 仅校验下限
        if ($validConfig['waitPayMin'] <= $amount) {
            return true;
        }

        // 上限不校验
//        if ($validConfig['waitPayMax'] >= $amount) {
//            return true;
//        }

        // 不能
        return false;
    }

    /**
     * 初始化店铺名称
     * @param string $contract
     * @return string
     */
    public static function initShopName(string $contract): string
    {
        return $contract . '的店';
    }

    /**
     * 商家建档
     * @return int[]
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function shopBuild(): array
    {
        $contact    = $this->signOrder->identityCardRel->name;
        $shopName   = self::initShopName($contact);
        $shopMobile = $this->signOrder->baseInfoRel->mobile;

        // 校验门店是否已建 - 幂等
        if ($this->signOrder->shopCode) {
            $shopId = (int)optional($this->signOrder->progressRel)->shopId;
            return [
                'shopId'   => $shopId,
                'shopCode' => $this->signOrder->shopCode,
                'password' => Cache::get(OpenShopCacheEnum::getShopManagerPwd($shopMobile)), // 下个版本可以删掉
            ];
        }

        // 阶段校验
        if ($this->signOrder->step < SignOrderEnum::STEP_4) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_BEFORE_CREATE_SHOP)
            );
        }

        // 校验门店是否已建
        if ($this->signOrder->shopCode) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_CREATE_SHOP_REPEATED)
            );
        }

        $shopId   = 0;
        $password = '';
        $shopCode = 0;

        // 导入订单，先判断shopCode是否存在，存在就不创建了
        if ($this->signOrder->provideShopCode) {
            $rmsShop = (new RmsShopApi())->getShopByCode($this->signOrder->provideShopCode);
            if ($rmsShop['code']) {
                $shopId   = $rmsShop['data']['id'];
                $shopCode = $this->signOrder->provideShopCode;
            }

            Log::warning("shopBuild provideShopCode:{$this->signOrder->provideShopCode} repeat...");
        }

        // 正常的建店逻辑
        if ($shopId == 0) {

            // 用户名需要增加改变，确保唯一性
            $contact .= ((string)optional($this->signOrder->contractRel)->id);

            // curl建店
            $response = (new RmsShopApi())->createShop($shopName, $shopMobile, $contact,
                $this->signOrder->provideShopCode);
            if (!isset($response['code']) || !$response['code']) {
                Log::warning("shopBuild err:", $response);
                throw new CustomHttpResponseException(
                    ErrCode::errCodeTrans(ErrCode::CODE_BUILD_SHOP_ERR, "建店失败：" . ($response['msg'] ?? ''))
                );
            }

            // 返回内容异常
            $shopId   = $response['data']['shopId'] ?? 0;
            $shopCode = $response['data']['shopCode'] ?? 0;
            $password = $response['data']['password'] ?? ''; // 以后这里都是空
        }

        if (!$shopId || !$shopCode) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_BUILD_SHOP_RESPONSE_NULL)
            );
        }

        // 更新shopCode
        $this->signOrder->saveShopCode($shopCode);

        // 更新shopId
        OpenShopMainProcessModel::saveShopId($this->signOrder->mainProcessId, $shopId);

        // 新增门店违约函版本
        CruiseCheckAgainstShopMappingsService::addAgainstVersionByShopId($shopId, $shopCode);

        // 新增默认班次
        ScheduleService::initShopScheduleRule($shopId);

        // 创建空门店资质空记录
        CruiseShopLicenseRecordsService::initShopLicense($shopId);

        return ['shopId' => $shopId, 'shopCode' => $shopCode, 'password' => $password];
    }

    // 准备支付
    public function preparePay(
        int $sysType,
        int $payChannel,
        string $h5BackUrl,
        int $amount,
        int $payAction,
        string $bizId,
        int $shopId,
        int $currentUid = 0
    ): array {
        if ($sysType == CheckEnum::SYS_TYPE_OPEN_SHOP_LEAGUE) {
            $bizId = $this->orderNo;
        }

        // 订单状态校验
        $sysTypeService = BasePaySysTypeService::getIns($sysType, $this->signOrder, null, $bizId);
        $sysTypeService->valid();

        // 校验金额
        if (!$this->orderPayValid($sysType, $amount, $sysTypeService->getOrderModel())) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_PAY_AMOUNT_ERR)
            );
        }

        if ($sysType == CheckEnum::SYS_TYPE_AGAINST) {
            $subject = $this->signOrder->shopCode . '-' . RmsPayEnum::SYS_TYPE_TEXT[$sysType];
        } else {

            // 备注: 姓名 + 加盟费
            $subject  = '';
            $userName = (string)optional($this->signOrder->identityCardRel)->name;
            if ($userName) {
                $subject = $userName . '-';
            }
            $subject .= RmsPayEnum::SYS_TYPE_TEXT[$sysType];
        }

        $this->payParam = new PayParamService($this->orderNo, $sysType, $payChannel, $payAction, $h5BackUrl, $amount,
            $subject, $bizId, $shopId, $currentUid);

        if ($payAction == RmsPayEnum::PAY_ACTION_WAP) {

            // wap支付
            return $this->payParam->prepareWapPay();
        } elseif ($payAction == RmsPayEnum::PAY_ACTION_APP) {

            // app支付
            return $this->payParam->prepareAppPay();
        }

        throw new CustomHttpResponseException(
            ErrCode::errCodeTrans(ErrCode::CODE_ERR_PAY_ACTION)
        );
    }

    /**
     * 单笔支付回调
     * @param int $payHistoryId
     * @param int $amount
     */
    public function paySuccess(int $payHistoryId, int $amount): void
    {
        // 更新支付流水表
        $payHistory = OpenShopSignOrderPayHistoryModel::query()
                                                      ->find($payHistoryId);
        if (!$payHistory) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_PAY_ID_NULL)
            );
        }
        $sysType = $payHistory->sysType;

        $sysTypeService = BasePaySysTypeService::getIns($sysType, $this->signOrder, null, $payHistory->bizId,
            $payHistory->createdByUid);

        // 支付幂等校验
        if ($sysTypeService->paySuccessCheck()) {
            return;
        }

        // 支付金额不一致
        if ($payHistory->payPrice != $amount) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_PAY_CALLBACK_PRICE)
            );
        }

        try {
            DB::beginTransaction();

            // 更新支付流水 - 成功
            if ($payHistory->payStatus != OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK) {
                OpenShopSignOrderPayHistoryModel::paySuccess($payHistoryId, time());
            }

            // 更新主订单
            $sysTypeService->paySuccessSaveOrder($amount);

            DB::commit();

        } catch (CustomHttpResponseException $e) {
            throw $e;
        } catch (\Exception $e) {
            Log::warning($e);
            DB::rollBack();

            // 支付回调异常
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_PAY_CALLBACK_ERR,
                    ErrCode::CODE_CN[ErrCode::CODE_SIGN_ORDER_PAY_CALLBACK_ERR] . ':' . $e->getMessage())
            );

        }

        // 支付成功之后的操作
        $sysTypeService->paySuccessAfter();
    }

    /**
     * 外部的支付成功调用
     * @param string $bizId
     */
    public function internalPaySuccess(string $bizId, int $payPrice, int $payChannel, string $payNo, int $sysType): int
    {
        if (!in_array($sysType, [
            CheckEnum::SYS_TYPE_OPEN_SHOP_EQUIPMENT,
            CheckEnum::SYS_TYPE_ROS,
            CheckEnum::SYS_TYPE_OPEN_SHOP_DECORATE
        ])) {

            // 支付回调异常
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_ERR_INTERNAL_OPEN_SHOP_PAY,
                    ErrCode::CODE_CN[ErrCode::CODE_ERR_INTERNAL_OPEN_SHOP_PAY] . ' sysType:' . $sysType)
            );
        }

        $addPayLogId = 0;
        if ($sysType == CheckEnum::SYS_TYPE_OPEN_SHOP_EQUIPMENT) {

            if (HistoryOrderParam::$importOrderMode) {
                $addPayLogId = $this->equipmentPayImport($bizId, $payPrice, $payChannel, $payNo, $sysType);
            } else {
                $addPayLogId = $this->softEquipmentPay($bizId, $payPrice, $payChannel, $payNo, $sysType);
            }
        } elseif ($sysType == CheckEnum::SYS_TYPE_OPEN_SHOP_DECORATE) {
            $addPayLogId = $this->softEquipmentPay($bizId, $payPrice, $payChannel, $payNo, $sysType);
        } elseif ($sysType == CheckEnum::SYS_TYPE_ROS) {
            $userName = (string)optional($this->signOrder->identityCardRel)->name;
            $subject  = $userName . '-' . RmsPayEnum::SYS_TYPE_TEXT[$sysType];
            if (HistoryOrderParam::$importOrderMode) {
                $subject .= '（历史补录）';
            }

            $payLog = OpenShopSignOrderPayHistoryModel::query()
                                                      ->where('orderNo', $this->orderNo)
                                                      ->where('sysType', $sysType)
                                                      ->where('payStatus',
                                                          OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK)
                                                      ->count();
            if (!$payLog) {

                // 新增pay_history记录
                $addPayLog = OpenShopSignOrderPayHistoryModel::addHistory($this->orderNo, $payPrice, $payPrice,
                    $payChannel,
                    OpenShopSignOrderPayHistoryModel::TYPE_FINAL, $subject, $sysType, $bizId,
                    OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK, time(), $payNo);

                // 首批订货，记录管理费
//                $main = OpenShopMainProcessModel::query()->where('orderNo', $this->orderNo)
//                                                ->select('shopId', 'startFeeTime')->first();
//                if (!$main->startFeeTime) {
//                    $startFeeTime = InitFeeDate::getStartFeeTime(time(), $main->shopId);
//                    OpenShopMainProcessModel::updateFee($this->orderNo, $startFeeTime);
//                }

                // 是否有收银工单
            }
        }

        return $addPayLogId;
    }

    // 设备单支付成功 - 导入模式
    private function equipmentPayImport(string $bizId, int $payPrice, int $payChannel, string $payNo, int $sysType): int
    {
        if (HistoryOrderParam::$forceCurrentUser) {
            $uid = HistoryOrderParam::$forceCurrentUser->id;
        } else {
            $uid = $this->signOrder->merchantUserId;
        }

        $userName = (string)optional($this->signOrder->identityCardRel)->name;
        $subject  = $userName . '-' . RmsPayEnum::SYS_TYPE_TEXT[$sysType];

        $addPayLogId = OpenShopSignOrderPayHistoryModel::addHistory($this->orderNo, $payPrice, $payPrice, $payChannel,
            OpenShopSignOrderPayHistoryModel::TYPE_FINAL, $subject, $sysType, $bizId,
            OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK, time(), $payNo);

        // 更新space_design表step
        OpenShopSpaceDesignModel::updateStep($this->orderNo,
            MainProcessEnum::SPACE_DESIGN_STEP_NEXT_STEP[MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_EQUIPMENT_PAY]);

        event(new SignSiteMissionEvent($this->signOrder->orderNo, MissionTemplateEnum::STEP_STATUS_16,
            $this->signOrder->merchantUserId));

        // 完成了事后的设备单支付通知
        event(new OpenShopProcessEvent($uid, $this->signOrder->mainProcessId,
            MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
            MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_EQUIPMENT_PAY));

        return $addPayLogId;
    }

    // 设备软装单支付成功
    private function softEquipmentPay(string $bizId, int $payPrice, int $payChannel, string $payNo, int $sysType): int
    {
        // 全部应付总金额
        $myEquipments   = collect(KfosService::myEquipments($this->orderNo, $sysType));
        $shouldPayPrice = (int)$myEquipments->map(function ($v) {
            return bcmul(bcmul($v["num"], 100), $v["saleUnitPrice"]);
        })->values()->sum();

        // 全部已支付金额
        // 判断是否是子单
        $openMain = OpenShopMainProcessModel::query()->where('orderNo', $this->orderNo)->first();

        $hasPayPrice = OpenShopSignOrderPayHistoryModel::query()
                                                       ->when($openMain->childLocationOrder,
                                                           function ($query) use ($openMain) {
                                                               $orderList = OpenShopMainProcessModel::query()
                                                                                                    ->select(['orderNo'])
                                                                                                    ->where('locationPid',
                                                                                                        $openMain->locationPid)
                                                                                                    ->orWhere('id',
                                                                                                        $openMain->locationPid)
                                                                                                    ->get()
                                                                                                    ->pluck('orderNo');
                                                               $query->whereIn('orderNo', $orderList);
                                                           }, function ($query) {
                                                               $query->where('orderNo', $this->orderNo);
                                                           })
                                                       ->where('sysType', $sysType)
                                                       ->where('payStatus',
                                                           OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK)
                                                       ->when($sysType == CheckEnum::SYS_TYPE_OPEN_SHOP_DECORATE,
                                                           function ($query) {
                                                               $query->where('bizId', 'like', 'D%'); // 软装订单，只统计新软装
                                                           })
                                                       ->sum('payPrice');

        // 全部剩余待支付
        $waitPayPrice = $shouldPayPrice - $hasPayPrice;

        // 支付金额溢出
        if ($payPrice > $waitPayPrice) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_ERR_PAY_PRICE_OVERFLOW,
                    ErrCode::CODE_CN[ErrCode::CODE_ERR_PAY_PRICE_OVERFLOW] . ':' . bcdiv100($waitPayPrice))
            );
        }

        // 插入流水记录
        $userName = (string)optional($this->signOrder->identityCardRel)->name;
        $subject  = $userName . '-' . RmsPayEnum::SYS_TYPE_TEXT[$sysType];

        $addPayLogId = OpenShopSignOrderPayHistoryModel::addHistory($this->orderNo, $payPrice, $payPrice,
            $payChannel,
            OpenShopSignOrderPayHistoryModel::TYPE_FINAL, $subject, $sysType, $bizId,
            OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK, time(), $payNo);


        // 本单应付金额
        $preparationShouldPayPrice = (int)$myEquipments->where('code', $bizId)->map(function ($v) {
            return bcmul(bcmul($v["num"], 100), $v["saleUnitPrice"]);
        })->values()->sum();


        // 本单已支付
        $hasPayPrice = OpenShopSignOrderPayHistoryModel::query()
                                                       ->where('orderNo', $this->orderNo)
                                                       ->where('bizId', $bizId)
                                                       ->where('sysType', $sysType)
                                                       ->where('payStatus',
                                                           OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK)
                                                       ->sum('payPrice');

        if ($sysType == CheckEnum::SYS_TYPE_OPEN_SHOP_EQUIPMENT) {
            $this->baseEquipmentPay($preparationShouldPayPrice, $hasPayPrice, $payPrice, $waitPayPrice, $addPayLogId,
                $bizId);
        } elseif ($sysType == CheckEnum::SYS_TYPE_OPEN_SHOP_DECORATE) {
            $this->baseSoftDecoratePay($preparationShouldPayPrice, $hasPayPrice, $payPrice, $waitPayPrice, $addPayLogId,
                $bizId);
        }

        return $addPayLogId;
    }

    // 软装单支付成功 - 2023.5.1后实施
    private function baseSoftDecoratePay(
        int $preparationShouldPayPrice,
        int $hasPayPrice,
        int $payPrice,
        int $waitPayPrice,
        int $addPayLogId,
        string $bizId
    ) {
        // 更新soft表
        $soft = OpenShopSpaceDesignSoftOutfitMappingModel::query()->where('newOrderCode', $bizId)->first();
        if ($soft) {
            $soft->onePaySuccess($payPrice, $preparationShouldPayPrice);
        }

        // 更新软装标签
        dispatch(function () {
            (new ShopTagsService($this->orderNo))->updateSoftPayTag();
        })->delay(3); // 异步执行，太早会更新不到

        // 单笔支付完成
        if ($soft->payStatus == OpenShopSpaceDesignSoftOutfitMappingModel::ORDER_PAY_STATUS_2) {



        // 完全支付完
//        if ($payPrice == $waitPayPrice) {

            // 判断阶段
            $nowStepStatus = (int)OpenShopMainProcessModel::query()->where('orderNo', $this->orderNo)
                                                          ->value('nowStepStatus');

            // 进入下一阶段
            if ($nowStepStatus == MissionTemplateEnum::STEP_STATUS_17) {

                // 更新space_design表step
                OpenShopSpaceDesignModel::updateStep($this->orderNo,
                    MainProcessEnum::SPACE_DESIGN_STEP_NEXT_STEP[MainProcessEnum::SPACE_DESIGN_STEP_TYPE_SOFT_OUTFIT_PAY]);

                event(new SignSiteMissionEvent($this->signOrder->orderNo, MissionTemplateEnum::STEP_STATUS_17,
                    $this->signOrder->merchantUserId));

                // 完成了事后的设备单支付通知
                event(new OpenShopProcessEvent($this->signOrder->merchantUserId, $this->signOrder->mainProcessId,
                    MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
                    MainProcessEnum::SPACE_DESIGN_STEP_TYPE_SPACE_FINISH));

            } else {

                // 支线的流程 - 支付成功，关闭任务即可
                OpenShopSiteMissionModel::finishBranchMission($this->signOrder->orderNo,
                    MissionTemplateEnum::STEP_STATUS_17);

                // 完成了事后的设备单支付通知
                event(new OpenShopProcessEvent($this->signOrder->merchantUserId, $this->signOrder->mainProcessId,
                    MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
                    MainProcessEnum::SPACE_DESIGN_STEP_TYPE_SPACE_FINISH));
            }

            //筹备阶段-在「软装模块支付」完成之后，进行推送 评价消息
            NotifyService::notify($this->orderNo, AppraiseModel::TYPE_OPENSHOP_PREPARATION, 0,
                $this->signOrder->progressRel->shopId);

            // 导入模式不推送
            if (HistoryOrderParam::$importOrderMode ) {
                return;
            }

            // 群消息推送
            SignOrderService::prepareOrderPaySuccessFsGroup($this->orderNo, '软装');
        }
    }

    // 设备支付成功
    private function baseEquipmentPay(
        int $preparationShouldPayPrice,
        int $hasPayPrice,
        int $payPrice,
        int $waitPayPrice,
        int $addPayLogId,
        string $bizId
    ) {
        // 其中一单支付完
        if ($preparationShouldPayPrice - $hasPayPrice <= 0) {

            // 判断阶段
            $nowStepStatus = (int)OpenShopMainProcessModel::query()->where('orderNo', $this->orderNo)
                                                          ->value('nowStepStatus');

            // 判断是不是第一次
            if ($nowStepStatus != MissionTemplateEnum::STEP_STATUS_16) {

                // 不是第一次了，关闭任务
                OpenShopSiteMissionModel::finishBranchMission($this->signOrder->orderNo,
                    MissionTemplateEnum::STEP_STATUS_16);
            } else {

                // 更新space_design表step
                OpenShopSpaceDesignModel::updateStep($this->orderNo,
                    MainProcessEnum::SPACE_DESIGN_STEP_NEXT_STEP[MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_EQUIPMENT_PAY]);

                event(new SignSiteMissionEvent($this->signOrder->orderNo, MissionTemplateEnum::STEP_STATUS_16,
                    $this->signOrder->merchantUserId));

                // 支付完成之后的推送 , 放置代码最后
                try {

                    // 加入设备支付通知
                    $this->notify($bizId);

                } catch (\Exception $exception) {
                    BuildFs::newRobot(SendFs::ROBOT_WARNING)->setTitleContent('设备模块支付后, 通知飞书异常报错', $exception)->send();
                }
            }

            event(new OpenShopProcessEvent($this->signOrder->merchantUserId, $this->signOrder->mainProcessId,
                MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
                MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_EQUIPMENT_PAY));

            // 群通知
            SignOrderService::prepareOrderPaySuccessFsGroup($this->orderNo, '设备');

            (new ShopTagsService($this->signOrder->orderNo))->updateKfosTag();
        }

        // 完全支付完
//        if ($payPrice == $waitPayPrice) {
//
//            // 判断阶段
//            $nowStepStatus = (int)OpenShopMainProcessModel::query()->where('orderNo', $this->orderNo)
//                                                          ->value('nowStepStatus');
//
//            // 进入下一阶段
//            if ($nowStepStatus != MissionTemplateEnum::STEP_STATUS_16) {
//
//                // 支线的流程 - 支付成功，关闭任务即可
//                OpenShopSiteMissionModel::finishBranchMission($this->signOrder->orderNo,
//                    MissionTemplateEnum::STEP_STATUS_16);
//            }
//
//            // 完成了事后的设备单支付通知
//            event(new OpenShopProcessEvent($this->signOrder->merchantUserId, $this->signOrder->mainProcessId,
//                MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
//                MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_EQUIPMENT_PAY));
//        }
    }

    /**
     * 设计、设备、软装订单支付成功通知
     * @param string $orderNo
     * @param string $prefix
     * @return void
     * @throws \Exception
     */
    public static function prepareOrderPaySuccessFsGroup(string $orderNo, string $prefix)
    {
        $signOrder = OpenShopSignOrderModel::query()->where('orderNo', $orderNo)->orderByDesc('id')->first();
        $shopCode = $signOrder->shopCode;

        // 商家名称
        $userName = (string)optional($signOrder->identityCardRel)->name;

        $elements = (new FsCardGrid())
            ->pushTd("**开店订单号：** {$orderNo}", false)
            ->pushTd("")
            ->pushTd("**门店编号：** {$shopCode}", false)
            ->pushTd("")
            ->pushTd("**任务处理角色：** " . '商家', false)
            ->pushTd("")
            ->pushTd("**任务处理人：** " . $userName, false)
            ->pushTd("")
            ->pushTd("**任务处理时间：** " . date('Y-m-d'), false)
            ->getElement();

        $url = BaseService::getOrderInfoWebAppUrl($orderNo);

        $card = (new FsCardEstablish())
            ->setHeader('blue', "商家已付款{$prefix}模块")
            ->pushElements($elements)
            ->pushElements(['tag' => 'hr'])
            ->setButton('查看', $url)
            ->getTemplateArr();

        BuildFs::newRobot(SendFs::ROBOT_PREPARATION_PAY_SUCCESS, BuildFs::MSG_TYPE_CARD)
               ->setCardContent($card)
               ->send();
    }

    public function notify($bizId): void
    {
        Log::info('shanghutong_notify_1', [
            'orderNo' => $this->signOrder->orderNo,
            'bizId'   => $bizId,
        ]);
        // 推送夸父收银
        // 判断是否存在收银订单支付
        $isHasRms      = false; // 是否拥有夸父收银系统
        $equipmentList = ProblemFeedbackService::getOrmOrderGoods($bizId);
        foreach ($equipmentList as $equipOne) {
            if (strpos($equipOne['goods_name'], '夸父数字化') !== false) {
                $isHasRms = true;
                break;
            }
        }
        // 门店提送提醒
        $pushUidMap = array_values(
            array_column(
                (RmsUserRemote::getShopManagerUserByShopId([$this->signOrder->progressRel->shopId])['lists'] ?? []),
                "userId"
            )
        );

        if ($isHasRms) {
            (new SendFsService($this->orderNo))->choubeiSend();
            // 短信通知
            (new SmsService())->aliyunSend($this->signOrder->baseInfoRel->mobile,
                config('sms.template.workOrderOpenShouYinjiNotify'), []);
            SystemNotifyService::customerBatchPush(
                $pushUidMap,
                '开通夸父收银功能提醒',
                "尊敬的夸父伙伴您好，夸父提醒您：收银系统需要申请收款账号，请点击查看详情，提交资料，申请功能开通。",
                config('webUrl.notify_web_cdn_url') . '#/pages/work-order/function-activation/form/index?type=105',
                $this->signOrder->mainProcessRel->shopId,
                SystemNotifyCenterModel::NOTIFY_TYPE_5
            );
        }

/*
        // 判断商户通
        $merchantFeeTotal = OpenShopSpaceDesignCostMappingModel::query()
                                                               ->where('orderNo', $this->signOrder->orderNo)
                                                               ->where('payStatus',
                                                                   OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_2)
                                                               ->where('orderStatus', '!=',
                                                                   OpenShopSpaceDesignCostMappingModel::ORDER_STATUS_3)
                                                               ->sum('merchantFee');

        Log::info('shanghutong_notify_2', [
            'orderNo'          => $this->signOrder->orderNo,
            'bizId'            => $bizId,
            'isHasRms'         => $isHasRms,
            'pushUidMap'       => $pushUidMap,
            'merchantFeeTotal' => $merchantFeeTotal
        ]);


        if ($merchantFeeTotal > 0) {
            // 飞书通知
            (new SendFsService($this->orderNo))->notifyChoubeiShangHuTongSend();

            SystemNotifyService::customerBatchPush(
                $pushUidMap,
                '开通夸父点评商户通提醒',
                "尊敬的夸父伙伴您好，您已完成点评商户通费用的支付。请点击查看详情，提交资料，申请点评商户通功能。",
                config('webUrl.notify_web_cdn_url') . '#/pages/work-order/function-activation/form/index?type=103',
                $this->signOrder->mainProcessRel->shopId,
                SystemNotifyCenterModel::NOTIFY_TYPE_5
            );
        }*/
    }

    /**
     * 支付状态查询
     * @param string $payNo
     * @return array
     */
    public function payStatus(string $payNo): array
    {
        $pay = OpenShopSignOrderPayHistoryModel::query()
                                               ->where('orderNo', $this->orderNo)
                                               ->where('payNo', $payNo)
                                               ->first();

        // payNo不存在
        if (!$pay) {
            \App\Service\BaseService::throwErr("支付中查询中...");
        }

        // 还需支付金额
        $lastPayPrice = 0;
        if ($pay->payStatus == OpenShopSignOrderPayHistoryModel::PAY_STATUS_OK) {
            $orderModel   = BasePaySysTypeService::getIns($pay->sysType, $this->signOrder, null, $pay->bizId)
                                                 ->getOrderModel();
            $lastPayPrice = $this->orderPayValidConfig($pay->sysType, $orderModel)['waitPaySum'];
        }

        return [
            'orderNo'      => $this->orderNo,
            'payNo'        => $payNo,
            'payStatus'    => $pay->payStatus,
            'payPrice'     => $pay->payPrice,
            'payTime'      => $pay->payTime,
            'payChannel'   => $pay->payChannel,
            'lastPayPrice' => $lastPayPrice,
        ];
    }

    /**
     * 生成子订单相关表
     * @param int $shopId
     * @param int $shopCode
     */
    public function createChildOrders(): string
    {
        // 生成子订单的orderNo
        $orderNo = MainProcessService::generateOrderNo();

        // mainProcess
        $parentMainProcess = $this->signOrder->progressRel;

        // 子订单要删除前两步
        $stepStatusLists = json_decode($parentMainProcess->stepStatusLists, true);
        foreach ($stepStatusLists as $k => $stepStatus) {
            if (in_array($stepStatus, [MissionTemplateEnum::STEP_STATUS_0, MissionTemplateEnum::STEP_STATUS_1])) {
                unset($stepStatusLists[$k]);
            }
        }

        $childMainProcess   = (new OpenShopMainProcessModel([
            'shopId'          => 0,
            'step'            => $parentMainProcess->step,
            'orderNo'         => $orderNo,
            'pid'             => $parentMainProcess->id,
            'childOrder'      => MainProcessEnum::CHILD_ORDER_1,
            'stepStatusLists' => json_encode(array_values($stepStatusLists)),
            'nowStepStatus'   => MissionTemplateEnum::STEP_STATUS_2,
        ]))->addData();
        $childMainProcessId = $childMainProcess->id;

        // 定金模式，子单处理金额
        /**
         * 存储逻辑：
         * 1. 主单 - 金额 = 1店 + 定金 * shopCount
         * 2. 子单 - 金额 = 1店尾款
         * 3. 子单付了尾款，就把金额减少。加到主单上去
         *
         * 显示调整：
         * 1. 主单 - 金额 = 加盟合计金额 / 实付金额
         * 2. 子单 - 金额 = 无脑显示 0 / 0
         */

        $shouldPayPrice = $payPrice = 0;
        $payStatus      = SignOrderEnum::PAY_STATUS_OK;
        $shopCount      = $this->signOrder->contractRel->shopCount;
        $depositAmountOne  = (int)($this->signOrder->contractRel->depositAmount / $shopCount);

        if ($this->signOrder->contractRel->mode == OpenShopContractTemplateModel::MODE_3) {

            // 子单 - 单店尾款
            $shouldPayPrice = (int)($this->signOrder->shouldPayPrice - $depositAmountOne * ($shopCount - 1) - $depositAmountOne);
            $payStatus      = SignOrderEnum::PAY_STATUS_PART;
        }

        // signOrder
        $childSignOrderArr                   = $this->signOrder->toArray();
        $childSignOrderArr['mainProcessId']  = $childMainProcess->id;
        $childSignOrderArr['step']           = SignOrderEnum::STEP_4;
        $childSignOrderArr['orderNo']        = $orderNo;
        $childSignOrderArr['shopCode']       = 0;
        $childSignOrderArr['shouldPayPrice'] = $shouldPayPrice;
        $childSignOrderArr['payPrice']       = $payPrice;
        $childSignOrderArr['payStatus']      = $payStatus;
        $childSignOrderArr['signTime']       = 0;
        $childSignOrderArr['createdAt']      = $childSignOrderArr['updatedAt'] = time();
        $childSignOrder                      = (new OpenShopSignOrderModel($childSignOrderArr))->addData();

        // userContract
        $this->signOrder->contractRel->replicate()
                                     ->fill(array_merge([
                                         'orderNo'       => $orderNo,
                                         'remark'        => null,
                                         'contractExtNo' => '',
                                         'createdAt'     => time(),
                                         'updatedAt'     => time(),
                                     ]))
                                     ->save();
        // baseInfo
        $this->signOrder->baseInfoRel
            ->replicate()
            ->fill([
                'orderNo'   => $orderNo,
                'createdAt' => time(),
                'updatedAt' => time()
            ])->save();

        // identity
        $this->signOrder->identityCardRel
            ->replicate()
            ->fill([
                'orderNo'   => $orderNo,
                'createdAt' => time(),
                'updatedAt' => time(),
            ])
            ->save();

        // work experience
        $this->signOrder->userExperienceRel
            ->replicate()
            ->fill([
                'orderNo'   => $orderNo,
                'createdAt' => time(),
                'updatedAt' => time(),
            ])
            ->save();

        // processDetail
        $this->signOrder->processDetailRel->where('mainProcessType', MainProcessEnum::MAIN_PROCESS_INVESTMENT_SIGN)
                                          ->whereIn('processType', [
                                              MainProcessEnum::INVESTMENT_SIGN_SUBMIT_SIGN_ORDER,
                                              MainProcessEnum::INVESTMENT_SIGN_CONTRACT_PAID
                                          ])
                                          ->each(function ($item) use ($childMainProcessId) {
                                              $item->replicate()->fill([
                                                  'mainProcessId' => $childMainProcessId,
                                              ])->save();
                                          });

        // signOrderLog
        $this->signOrder->signOrderLogRel
            ->where('type', OpenShopSignOrderLogModel::TYPE_ORDER_CREATED)
            ->each(function ($item) use ($childSignOrder) {
                $item->replicate()->fill([
                    'orderId' => $childSignOrder->id,
                ])->save();
            });

        // orderManager
        OpenShopOrderManagerModel::generateManagerOrUpdate(
            OpenShopOrderManagerModel::MANAGER_TYPE_1,
            $childMainProcessId,
            $this->signOrder->investmentManagerId,
            $this->signOrder->investmentManagerName,
        );

        // 自动生成address
        OpenShopAddressModel::autoAdd($orderNo);

        return $orderNo;
    }

    /**
     * 查询店铺信息
     * @return array
     */
    public function getShop(): array
    {
        if ($this->signOrder->shopCode) {

            // 查shop信息
            $shop = SiteMissionService::getRmsShopNameByCode([$this->signOrder->shopCode], ['id', 'name'],
                1)['shopList'][0] ?? [];
        }

        return $shop ?? [];
    }

    /**
     * 设计费支付详情
     * @return array
     */
    public function payDesignDetail(string $preparationNo): array
    {
        $order = OpenShopSpaceDesignCostMappingModel::query()
                                                    ->where('orderNo', $this->orderNo)
                                                    ->where('preparationNo', $preparationNo)
                                                    ->first();

        if (!$order) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_ERR_PAY_DETAIL)
            );
        }

        $payStatus = $order->payStatus;
        if ($payStatus > SignOrderEnum::PAY_STATUS_OK) {
            $payStatus = SignOrderEnum::PAY_STATUS_OK;
        }

        return [
            'pay' => array_merge([
                'payStatus'       => $payStatus,
                'deadLineSeconds' => $order->createdAt->timestamp + SignOrderEnum::DESIGN_DEADLINE_SECONDS - time(),

            ], $this->orderPayValidConfig(CheckEnum::SYS_TYPE_OPEN_SHOP_DESIGN, $order)),

            'order' => [
                'orderNo'       => $this->orderNo,
                'preparationNo' => $order->preparationNo,
            ],
        ];
    }

    /**
     * 年管理费支付详情
     * @param string $feeOrderNo
     * @return array
     */
    public function payAnnualDetail(int $userId, array $shopIds): array
    {
        if (!$shopIds) {

            // 查名下所有
            $shopIds = Cache::remember("getShopIdsByUserManager:{$userId}", 300, function () use ($userId) {
                return (new RmsUserApi())->getShopIdsByUserManager($userId)['data']['shopIds'] ?? [];
            });
        }

        $order = FeeAnnualOrderModel::query()
                                    ->whereIn('shopId', $shopIds)
                                    ->where('payStatus', '!=', FeeAnnualOrderModel::PAY_STATUS_OK)
                                    ->orderBy('endTime')
                                    ->with('mainProcessRel')
                                    ->first();
        if (!$order) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "所有年费订单均已支付");
        }

        $shop           = (new RmsShopApi())->getShopByIds([$order->shopId], ['shopCode', 'name'],
            true)['data']['shopList'][0] ?? [];
        $startFeeTime   = $order->mainProcessRel->startFeeTime;
        $startFeeTimeMD = date('md', strtotime($startFeeTime));


        $year = $order->startYear;
        if (!$year) {

            // 兼容一下
            $year = date('Y', $order->endTime);
        }

        return [
            'pay' => array_merge([
                'payStatus' => $order->payStatus,

            ], $this->orderPayValidConfig(CheckEnum::SYS_TYPE_ANNUAL_FEE, $order)),

            'order' => [
                'shopId'      => $order->shopId,
                'orderNo'     => $this->orderNo,
                'feeOrderNo'  => $order->feeOrderNo,
                'shopCode'    => str_pad($shop['shopCode'] ?? 0, 4, "0", STR_PAD_LEFT),
                'shopName'    => $shop['name'] ?? '',
                'expireTime'  => date('Y-m-d H:i:s', $order->endTime),
                'indateStart' => date('Y.m.d', strtotime($year . $startFeeTimeMD) + 86400),
                'indateEnd'   => date('Y.m.d', strtotime(($year + 1) . $startFeeTimeMD))
            ],
        ];
    }

    /**
     * 软装费支付详情
     * @param string $preparationNo
     * @return array
     */
    public function payDecorateDetail(string $preparationNo): array
    {
        $order = OpenShopSpaceDesignSoftOutfitMappingModel::query()
                                                          ->where('orderNo', $this->orderNo)
                                                          ->where('preparationNo', $preparationNo)
                                                          ->first();

        if (!$order) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_ERR_PAY_DETAIL)
            );
        }

        $payStatus = $order->payStatus;
        if ($payStatus > SignOrderEnum::PAY_STATUS_OK) {
            $payStatus = SignOrderEnum::PAY_STATUS_OK;
        }

        $priceFile = UploadFileResourceService::getFileList($this->orderNo,
            [UploadFileResourceEnum::SPACE_DESIGN_SOFT_XLSX])['softOutfitXlsx'][0] ?? '';

        return [
            'pay' => array_merge([
                'payStatus'       => $payStatus,
                'deadLineSeconds' => $order->createdAt->timestamp + SignOrderEnum::DECORATE_DEADLINE_SECONDS - time(),
                'priceFile'       => $priceFile,

            ], $this->orderPayValidConfig(CheckEnum::SYS_TYPE_OPEN_SHOP_DECORATE, $order)),

            'order' => [
                'orderNo'       => $this->orderNo,
                'preparationNo' => $order->preparationNo,
            ],
        ];
    }

    /**
     * 违约函支付详情
     * @param string $feeOrderNo
     * @return array
     */
    public function payAgainstDetail(int $againstId, int $shopId): array
    {
        $order = CruiseCheckAgainstModel::query()->where('id', $againstId)->where('shopId', $shopId)->first();
        if (!$order) {
            \App\Service\BaseService::throwErr("不存在的违约函");
        }

        if ($order->status != CruiseCheckAgainstModel::STATUS_WAIT) {
            \App\Service\BaseService::throwErr("违约函状态错误不能支付");
        }

        if ($order->price == 0) {
            \App\Service\BaseService::throwErr("违约函未生成金额");
        }

        $shop = (new RmsShopApi())->getShopByIds([$shopId], ['shopCode'],
            true)['data']['shopList'][0]['kfShopCode'] ?? [];

        return [
            'pay' => array_merge([
                'payStatus'       => $order->status == CruiseCheckAgainstModel::STATUS_OK ? 1 : 0,
                'deadLineSeconds' => $order->endTime - time(),

            ], $this->orderPayValidConfig(CheckEnum::SYS_TYPE_AGAINST, $order)),

            'order' => [
                'orderNo'    => $this->signOrder->orderNo,
                'bizId'      => (string)$againstId,
                'expireTime' => date('Y-m-d H:i:s', $order->endTime),
                'serialNum'  => $order->serialNum,
                'level'      => $order->level,
                'levelText'  => CruiseCheckAgainstModel::LEVEL_TEXT[$order->level] ?? '',
                'content'    => '违约函正文', // TODO
                'shopId'     => $shopId,
                'shopCode'   => $shop['kfShopCode'] ?? '',
                'shopName'   => $shop['name'] ?? '',
            ],
        ];
    }
}
